﻿using System;
using SSG.Tools;

namespace SSG.Model
{
    /// <summary>
    /// Edge between two fixes
    /// </summary>
    public class Leg
    {
        public static string KmlPlacemarkStyle = typeof (Leg).GetClassname();

        /// <summary>
        /// From fixpoint
        /// </summary>
        public Fix From { get; set; }

        /// <summary>
        /// From fixpoint
        /// </summary>
        public Fix To { get; set; }

        /// <summary>
        /// Distance to next Fixpoint
        /// </summary>
        public double DistanceKm { get; set; }

        /// <summary>
        /// Track
        /// </summary>
        public double TrackDeg { get; set; }

        /// <summary>
        /// Track
        /// </summary>
        public string TrackDegUnit { get { return this.TrackDeg.UnitDeg(); } }

        /// <summary>
        /// Difference in altitudes
        /// </summary>
        public double AltitudeDifferenceFt
        {
            get
            {
                if (this.From == null || this.To == null) return 0;
                if (this.From.AltitudeRestriction == null || this.To.AltitudeRestriction == null) return 0;
                return this.From.AltitudeRestriction.ValueFt - this.To.AltitudeRestriction.ValueFt;
            }
        }

        /// <summary>
        /// Difference in altitudes
        /// </summary>
        public double AltitudeDifferenceM
        {
            get
            {
                if (this.From == null || this.To == null) return 0;
                if (this.From.AltitudeRestriction == null || this.To.AltitudeRestriction == null) return 0;
                return this.From.AltitudeRestriction.ValueM - this.To.AltitudeRestriction.ValueM;
            }
        }

        /// <summary>
        /// Altitude difference
        /// </summary>
        public string AltitudeDifferenceUnitM { get { return this.AltitudeDifferenceM.UnitM(); } }

        /// <summary>
        /// Altitude difference
        /// </summary>
        public string AltitudeDifferenceUnitFt { get { return this.AltitudeDifferenceFt.UnitFt(); } }

        /// <summary>
        /// Distance to next Fixpoint
        /// </summary>
        public double DistanceNm { get { return this.DistanceKm.KilometersToNauticalMiles(); } set { this.DistanceKm = value.NauticalMilesToKilometers(); } }

        /// <summary>
        /// Distance
        /// </summary>
        public string DistanceKmUnit { get { return this.DistanceKm.UnitKm(); } }

        /// <summary>
        /// Distance
        /// </summary>
        public string DistanceNmUnit { get { return this.DistanceNm.UnitNm(); } }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="distanceKm"></param>
        /// <param name="track"></param>
        public Leg(Fix from, Fix to, double distanceKm, double track)
        {
            if (from == null) throw new ArgumentNullException("from");
            if (to == null) throw new ArgumentNullException("to");
            this.From = from;
            this.To = to;
            this.DistanceKm = distanceKm;
            this.TrackDeg = track;
        }

        /// <summary>
        /// KML
        /// </summary>
        /// <param name="level"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public string ToKml(int level, GeneratorSettings settings)
        {
            double lat = 0.5*(this.From.Latitude + this.To.Latitude);
            double lng = 0.5*(this.From.Longitude + this.To.Longitude);
            string name = this.DistanceKmUnit + " " + this.TrackDegUnit;
            return Kml.Placemark(name, null, KmlPlacemarkStyle, lat, lng, level, false, settings);
        }
    }
}